package com.sinopec.basemodule.https;

import android.content.Context;

import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.Registry;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.module.GlideModule;
import com.sinopec.basemodule.http.dns.OkHttpDns;
import com.sinopec.basemodule.https.certification.TrustAllCerts;

import java.io.InputStream;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;

/**
 * A {@link GlideModule} implementation to replace Glide's default
 * {@link java.net.HttpURLConnection} based {@link com.bumptech.glide.load.model.ModelLoader}
 * with an OkHttp based {@link com.bumptech.glide.load.model.ModelLoader}.
 *
 * <p> If you're using gradle, you can include this module simply by depending on the aar, the
 * module will be merged in by manifest merger. For other build systems or for more more
 * information, see {@link GlideModule}. </p>
 *
 * @deprecated Replaced by {@link OkHttpLibraryGlideModule} for Applications that use Glide's
 * annotations.
 */
@Deprecated
public class OkHttpGlideModule implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // Do nothing.
    }

    @Override
    public void registerComponents(Context context, Glide glide, Registry registry) {
        //下面代码看https://github.com/square/okhttp/wiki/HTTPS
        //https用ConnectionSpec.MODERN_TLS，不是的就用ConnectionSpec.CLEARTEXT
        ConnectionSpec spec = null;
//        if (RetroAPIFactory.BASEURL.startsWith("https")) {
            spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                    .tlsVersions(TlsVersion.TLS_1_3,
                            TlsVersion.TLS_1_2)
                    .cipherSuites(
                            // TLSv1.3.
                            CipherSuite.TLS_AES_128_GCM_SHA256,
                            CipherSuite.TLS_AES_256_GCM_SHA384,
                            CipherSuite.TLS_CHACHA20_POLY1305_SHA256,

                            // TLSv1.0, TLSv1.1, TLSv1.2.
                            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                            CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
                            CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
                            CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
                            CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,

                            // Note that the following cipher suites are all on HTTP/2's bad cipher suites list. We'll
                            // continue to include them until better suites are commonly available.
                            CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
                            CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
                            CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
                            CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384,
                            CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
                            CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
                            CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA)
                    .build();
//        } else {
//            spec = new ConnectionSpec.Builder(ConnectionSpec.CLEARTEXT)
//                    .build();
//        }

        //用来解决https需要证书认证的问题
        SSLSocketFactory ssfFactory;
        X509TrustManager trustManager;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            trustManager = new TrustAllCerts();
            sc.init(null, new TrustManager[]{trustManager}, null);
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
            RuntimeException runtimeException = new RuntimeException("证书认证异常！");
            throw runtimeException;
        }

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder
                .dns(OkHttpDns.getInstance())
                .sslSocketFactory(ssfFactory, trustManager)
                .connectionSpecs(Collections.singletonList(spec))
                .hostnameVerifier((s, sslSession) -> {
                    return true;
//                        return "test.image.tankchaoren.com".equals(s)
//                                || "test.carrierapi.tankchaoren.com".equals(s);
                });

        builder.connectTimeout(20, TimeUnit.SECONDS);
        builder.readTimeout(20, TimeUnit.SECONDS);

        registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(builder.build()));
    }
}
